package newsrecommendation.datamodel;

import newsrecommendation.datamodel.utils.DemographicStatistics;
import newsrecommendation.datamodel.utils.Scores;
import newsrecommendation.datamodel.utils.UserType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import newsrecommendation.datamodel.keywords.NewsKeywords;
import newsrecommendation.datamodel.keywords.UserKeywords;
import newsrecommendation.utils.ListUtils;

/**
 *
 * @author Andrea
 */
public class UserProfile {

    private String id;
    private UserType userType;
    private UserKeywords interest;
    private HashMap<String, Double> likeHistory;
    private HashMap<String, Double> clickHistory;
    private HashMap<String, Double> newsScores;
    private double maxScore;

    public UserProfile(String id, UserType userType) {
        this.id = id;
        this.userType = userType;
        interest = new UserKeywords();
        likeHistory = new HashMap();
        clickHistory = new HashMap();
        newsScores = new HashMap();
        maxScore = 0;
        //Initial Profile
        interest.setInterests(new ArrayList(DemographicStatistics.get().getDemographicInterests(userType)));
    }

    public String getId() {
        return id;
    }

    public UserType getUserType() {
        return userType;
    }

    //EXPLICIT INTEREST
    public void setInterests(String csv_Keywords) {
        interest.setInterests(csv_Keywords);
    }

    public void setInterests(NewsKeywords keywords) {
        interest.setInterests(keywords);
    }

    public void setInterestsPosition(String csv_Positions) {
        interest.setInterestsPositions(csv_Positions);
    }

    //CLICK
    public void setClickNews(String newsId, String csv_newsKeywords) {
        addToClickHistory(newsId);
        interest.setClickNews(csv_newsKeywords);
    }

    public void setClickNews(String newsId, NewsKeywords keywords) {
        addToClickHistory(newsId);
        interest.setClickNews(keywords);
    }

    private void addToClickHistory(String newsId) {
        if (clickHistory.containsKey(newsId)) {
            clickHistory.put(newsId, clickHistory.get(newsId) + 1.0);
        } else {
            PopularityManager.get().setClick(newsId);
            clickHistory.put(newsId, 1.0);
        }
    }

    //LIKE
    public void setLikeNews(String newsId, String csv_newsKeywords) {
        if (isLike(newsId)) {
            removeLikeNews(newsId, csv_newsKeywords);
        } else {
            addToLikeHistory(newsId);
            interest.setLikeNews(csv_newsKeywords);
        }
    }

    public void setLikeNews(String newsId, NewsKeywords keywords) {
        if (isLike(newsId)) {
            removeLikeNews(newsId, keywords);
        } else {
            addToLikeHistory(newsId);
            interest.setLikeNews(keywords);
        }
    }

    private void addToLikeHistory(String newsId) {
        if (!likeHistory.containsKey(newsId)) {
            PopularityManager.get().setLike(newsId);
        }
        likeHistory.put(newsId, 1.0);
    }

    private void removeLikeNews(String newsId, String csv_newsKeywords) {
        removeFromLikeHistory(newsId);
        interest.removeLikeNews(csv_newsKeywords);
    }

    private void removeLikeNews(String newsId, NewsKeywords keywords) {
        removeFromLikeHistory(newsId);
        interest.removeLikeNews(keywords);
    }

    private void removeFromLikeHistory(String newsId) {
        if (likeHistory.containsKey(newsId)) {
            if (likeHistory.get(newsId) == 1) {
                likeHistory.put(newsId, 0.0);
            }
        }
    }

    public boolean isLike(String newsId) {
        if (likeHistory.containsKey(newsId)) {
            if (likeHistory.get(newsId) == 1) {
                return true;
            }
        }
        return false;
    }

    //SCORE
    public double calculateScore(String newsId, NewsKeywords newsKeywords) {
        double score = interest.getInterestNewsScore(newsKeywords);
        newsScores.put(newsId, score);
        return score;
    }

    public double calculateScore(String newsId, String csv_newsKeywords) {
        double score = interest.getInterestNewsScore(csv_newsKeywords);
        newsScores.put(newsId, score);
        return score;
    }

    //GET TOP K
    public List<String> getTopKNews(int K, List<String> available) {
        List<String> keys = new ArrayList(available);
//        for (int i = 0 ; i<available.size(); i++){
//        	keys.add(new String(available.get(i)));
//        }
        List<Double> values = new ArrayList();
        //Find values for available
        for (int i = 0; i < keys.size(); i++) {
            if (newsScores.containsKey(keys.get(i))) {
                values.add(newsScores.get(keys.get(i)));
            } else {
                values.add(0.0);
            }
        }
        
        List<String> organizedKeys = ListUtils.organizeKeys(keys, values);
        
        System.out.println(values);
        maxScore = newsScores.get(organizedKeys.get(0));

        if (organizedKeys.size() < K) {
            K = organizedKeys.size();
        }

        return organizedKeys.subList(0, K);
    }

    //News Size
    public int getNewsSize(NewsKeywords newsKeywords) {
        double newsScore = 0;
        newsScore = interest.getInterestNewsScore(newsKeywords);
        return getSize(newsScore);

    }

    public int getNewsSize(String newsId) {
        double newsScore = 0;
        if (newsScores.containsKey(newsId)) {
            newsScore = newsScores.get(newsId);
        }
        return getSize(newsScore);
    }

    private int getSize(double newsScore) {
        double eval = 0;
        if (maxScore != 0) {
            eval = newsScore / maxScore * 100;
        }
        if (eval > Scores.SIZE_THRESHOLD) {
            return Scores.SIZE_LARGE;
        } else {
            return Scores.SIZE_SMALL;
        }
    }

//TODO - BORRAR
    @Override
    public String toString() {
        return id + interest.getKeywordsScore();
    }
}
